1 Example hpgltool usage with a real data set (fission)

This document aims to provide further examples in how to use the hpgltools.

Note to self, the header has rmarkdown::pdf_document instead of html_document or html_vignette because it gets some bullcrap error ‘margins too large’…

1.1 Setting up

Here are the commands I invoke to get ready to play with new data, including everything required to install hpgltools, the software it uses, and the fission data.

if (! "BiocManager" %in% installed.packages()) {
  source("http://bioconductor.org/biocLite.R")
}
if (! "devtools" %in% installed.packages()) {
  biocManager::install("devtools")
}
if (! "hpgltools" %in% installed.packages()) {
  devtools::install_github("elsayed-lab/hpgltools")
}
if (! "fission" %in% installed.packages()) {
  biocManager::install("fission")
}
## I use the function 'sm()' to quiet loud functions.
tt <- sm(library(fission))
tt <- sm(data(fission))

1.2 Data import

All the work I do in Dr. El-Sayed’s lab makes some pretty hard assumptions about how data is stored. As a result, to use the fission data set I will do a little bit of shenanigans to match it to the expected format. Now that I have played a little with fission, I think its format is quite nice and am likely to have my experiment class instead be a SummarizedExperiment.

## Extract the meta data from the fission dataset
meta <- as.data.frame(fission@colData)
## Make conditions and batches
meta$condition <- paste(meta$strain, meta$minute, sep=".")
meta$batch <- meta$replicate
meta$sample.id <- rownames(meta)
## Grab the count data
fission_data <- fission@assays$data$counts
## This will make an experiment superclass called 'expt' and it contains
## an ExpressionSet along with any arbitrary additional information one might want to include.
## Along the way it writes a Rdata file which is by default called 'expt.Rdata'
fission_expt <- create_expt(metadata=meta, count_dataframe=fission_data)
## Reading the sample metadata.
## The sample definitions comprises: 36 rows(samples) and 7 columns(metadata fields).
## Matched 7039 annotations and counts.
## Bringing together the count matrix and gene information.
## Saving the expressionset to 'expt.rda'.
## The final expressionset has 7039 rows and 36 columns.

1.3 Normalizing and exploring data

There are lots of toys we have learned to use to play with with raw data and explore stuff like batch effects or non-canonical distributions or skewed counts. hpgltools provides some functionality to make this process easier. The graphs shown below and many more are generated with the wrapper ‘graph_metrics()’ but that takes away the chance to explain the graphs as I generate them.

## First make a bar plot of the library sizes in the experiment.
## Notice that the colors were auto-chosen by create_expt() and they should
## be maintained throughout this process
fis_libsize <- plot_libsize(fission_expt)
fis_libsize$plot

## Here we see that the wild type replicate 3 sample for 15 minutes has fewer non-zero genes than all its friends.
fis_nonzero <- plot_nonzero(fission_expt, labels="boring", title="nonzero vs. cpm")
fis_nonzero$plot

fis_density <- plot_density(fission_expt)
## This data will benefit from being displayed on the log scale.
## If this is not desired, set scale='raw'
## Some entries are 0.  We are on log scale, setting them to 0.5.
## Changed 24130 zero count features.
fis_density$plot

knitr::kable(fis_density$condition_summary)
condition min 1st median mean 3rd max
wt.0 0.5 31 216 1839 647 5346309
wt.15 0.5 20 135 1819 474 6733064
wt.30 0.5 27 183 1917 559 6722419
wt.60 0.5 27 195 1676 627 5034452
wt.120 0.5 25 183 1540 529 4531663
wt.180 0.5 29 210 1904 600 7223993
mut.0 0.5 35 238 1826 716 4818286
mut.15 0.5 22 142 1582 461 4387929
mut.30 0.5 33 226 2028 684 6061779
mut.60 0.5 39 279 1981 772 5268796
mut.120 0.5 35 242 1763 675 4174104
mut.180 0.5 24 178 1534 510 4276682
knitr::kable(fis_density$batch_summary)
batch min 1st median mean 3rd max
r1 0.5 30 205 1908 632 6733064
r2 0.5 28 193 1727 586 7223993
r3 0.5 27 196 1717 600 6722419
knitr::kable(head(fis_density$sample_summary))
sample min 1st median mean 3rd max
GSM1368273 0.5 46 306 2226 869.0 4542884
GSM1368274 0.5 21 147 1345 411.0 4117160
GSM1368275 0.5 34 243 1946 678.0 5346309
GSM1368276 0.5 34 226 2625 751.5 6733064
GSM1368277 0.5 20 123 1471 393.0 4094540
GSM1368278 0.5 13 95 1360 312.0 4714248

1.3.1 An initial pca plot

In most cases, raw data does not cluster very well, lets see if that is also true for the fission experiment. Assuming it doesn’t, lets normalize the data using the defaults (cpm, quantile, log2) and try again.

## Something in this is causing a build loop on travis...
## Unsurprisingly, the raw data doesn't cluster well at all...
##fis_rawpca <- plot_pca(fission_expt, expt_names=fission_expt$condition, cis=NULL)
fis_rawpca <- plot_pca(fission_expt)
fis_rawpca$plot

## So, normalize the data
norm_expt <- sm(normalize_expt(fission_expt, transform="log2", norm="quant", convert="cpm"))
## And try the pca again
fis_normpca <- plot_pca(norm_expt, plot_labels="normal", title="normalized pca", cis=NULL)
fis_normpca$plot

## Clearly time is an important factor in the data.

1.4 Try something for Najib

testing <- plot_pca(norm_expt, num_pc=3)
silly <- plot_3d_pca(testing)
silly$plot

In the final line of the preceeding block, I printed a summary of the return from plot_pca(). It contains the following information:

  • pca: The result from the fast.svd() call.
  • plot: The ggplot2 pca plot.
  • table: The metadata used to make the pca plot.
  • res: A table of the residual variance after each component by condition/batch.
  • variance: A numeric list of the %variance remaining after each PC.

With that in mind, lets perform some more pca plots after normalizing the data and see how different they look.

normbatch_expt <- sm(normalize_expt(fission_expt, transform="log2", norm="quant",
                                    convert="cpm", batch="sva"))
fis_normbatchpca <- plot_pca(normbatch_expt,
                             title="Normalized PCA with batch effect correction.", cis=NULL)
fis_normbatchpca$plot

## ok, that caused the 0, 60, 15, and 30 minute samples to cluster nicely
## the 120 and 180 minute samples are still a bit tight

## pca_information provides some more information about the call to
## fast.svd that went into making the pca plot
fis_info <- pca_information(norm_expt,
                            expt_factors=c("condition","batch","strain","minute"),
                            num_components=6)
## More shallow curves in these plots suggest more genes in this principle component.

## The r^2 table shows that quite a lot of the variance in the data is explained by condition
knitr::kable(head(fis_info$rsquared_table))
prop_var cum_prop_var condition_rsquared batch_rsquared
36.64 36.64 0.9914 0.0002
14.01 50.65 0.9667 0.0038
8.43 59.08 0.6640 0.2510
5.81 64.89 0.3872 0.2659
5.18 70.07 0.8888 0.0514
3.63 73.70 0.1516 0.0095
## We can look at the correlation between the principle components and the factors in the experiment
## in this case looking at condition/batch vs the first 4 components.
knitr::kable(fis_info$pca_cor)
PC1 PC2 PC3 PC4 PC5 PC6
condition 0.3160 -0.2694 -0.0582 -0.3246 0.0374 0.2853
batch 0.0123 -0.0606 0.5008 -0.5105 -0.2260 0.0969
strain 0.0351 -0.0077 0.1354 -0.2467 0.0562 0.2782
minute 0.5772 -0.5310 -0.3556 -0.2228 -0.0230 0.0881
## And p-values to lend some credence(or not to those assertions)
knitr::kable(fis_info$anova_p)
PC1 PC2 PC3 PC4 PC5 PC6
condition 0.0604 0.1121 0.7358 0.0534 0.8284 0.0916
batch 0.9431 0.7255 0.0019 0.0015 0.1850 0.5739
strain 0.8391 0.9645 0.4310 0.1469 0.7449 0.1004
minute 0.0002 0.0009 0.0333 0.1915 0.8940 0.6094
## Try again with batch removed data
batchnorm_expt <- sm(normalize_expt(fission_expt, batch="limma", norm="quant",
                                    transform="log2", convert="cpm"))
fis_batchnormpca <- plot_pca(batchnorm_expt, plot_title="limma corrected pca")
fis_batchnormpca$plot

test_pca <- pca_information(batchnorm_expt,
                            expt_factors=c("condition","batch","strain","minute"),
                            num_components=6)
## More shallow curves in these plots suggest more genes in this principle component.

Interesting, the batch normalized pca plot looks much the same as the normalized. The variances are in fact pretty much the exact same…

1.5 Look at the data distributions

We have some tools which provide visualizations of the distribution of the data:

fission_boxplot <- sm(plot_boxplot(fission_expt))
fission_boxplot

sf_expt <- sm(normalize_expt(fission_expt, norm="sf"))
fission_boxplot <- sm(plot_boxplot(sf_expt))
fission_boxplot

tm_expt <- sm(normalize_expt(fission_expt, norm="tmm"))
fission_boxplot <- sm(plot_boxplot(tm_expt))
fission_boxplot

rle_expt <- sm(normalize_expt(fission_expt, norm="rle"))
fission_boxplot <- sm(plot_boxplot(rle_expt))
fission_boxplot

up_expt <- sm(normalize_expt(fission_expt, norm="upperquartile"))
fission_boxplot <- sm(plot_boxplot(up_expt))
fission_boxplot

fission_density <- plot_density(norm_expt)
fission_density$plot

fission_density <- plot_density(sf_expt)
## This data will benefit from being displayed on the log scale.
## If this is not desired, set scale='raw'
## Some entries are 0.  We are on log scale, setting them to 0.5.
## Changed 24130 zero count features.
fission_density$plot

fission_density <- plot_density(tm_expt)
## This data will benefit from being displayed on the log scale.
## If this is not desired, set scale='raw'
## Some entries are 0.  We are on log scale, setting them to 0.5.
## Changed 24130 zero count features.
fission_density$plot

compare_12 <- plot_single_qq(fission_expt, x=1, y=2)
compare_12$log

1.6 See how they cluster

Ok, so we can further check out how the data cluster with respect to one another…

fission_cor <- plot_corheat(norm_expt)

fission_cor$plot
fission_cor <- plot_corheat(batchnorm_expt)

fission_cor$plot
fission_dis <- plot_disheat(norm_expt)

fission_dis$plot
fission_dis <- plot_disheat(batchnorm_expt)

fission_dis$plot

2 variancePartition

variancePartition may be used to seek out which experimental factors correlate with the most variance in the data.

test_varpart <- simple_varpart(fission_expt, predictor=NULL, factors=c("condition","batch"))
## Attempting mixed linear model with: ~  (1|condition) + (1|batch)
## Fitting the expressionset to the model, this is slow.
## Dividing work into 100 chunks...
## Warning in serialize(data, node$con, xdr = FALSE): 'package:variancePartition'
## may not be available when loading

## Warning in serialize(data, node$con, xdr = FALSE): 'package:variancePartition'
## may not be available when loading

## Warning in serialize(data, node$con, xdr = FALSE): 'package:variancePartition'
## may not be available when loading

## Warning in serialize(data, node$con, xdr = FALSE): 'package:variancePartition'
## may not be available when loading

## Warning in serialize(data, node$con, xdr = FALSE): 'package:variancePartition'
## may not be available when loading

## Warning in serialize(data, node$con, xdr = FALSE): 'package:variancePartition'
## may not be available when loading

## Warning in serialize(data, node$con, xdr = FALSE): 'package:variancePartition'
## may not be available when loading

## Warning in serialize(data, node$con, xdr = FALSE): 'package:variancePartition'
## may not be available when loading

## Warning in serialize(data, node$con, xdr = FALSE): 'package:variancePartition'
## may not be available when loading

## Warning in serialize(data, node$con, xdr = FALSE): 'package:variancePartition'
## may not be available when loading

## Warning in serialize(data, node$con, xdr = FALSE): 'package:variancePartition'
## may not be available when loading

## Warning in serialize(data, node$con, xdr = FALSE): 'package:variancePartition'
## may not be available when loading

## Warning in serialize(data, node$con, xdr = FALSE): 'package:variancePartition'
## may not be available when loading

## Warning in serialize(data, node$con, xdr = FALSE): 'package:variancePartition'
## may not be available when loading

## Warning in serialize(data, node$con, xdr = FALSE): 'package:variancePartition'
## may not be available when loading

## Warning in serialize(data, node$con, xdr = FALSE): 'package:variancePartition'
## may not be available when loading

## Warning in serialize(data, node$con, xdr = FALSE): 'package:variancePartition'
## may not be available when loading

## Warning in serialize(data, node$con, xdr = FALSE): 'package:variancePartition'
## may not be available when loading

## Warning in serialize(data, node$con, xdr = FALSE): 'package:variancePartition'
## may not be available when loading

## Warning in serialize(data, node$con, xdr = FALSE): 'package:variancePartition'
## may not be available when loading

## Warning in serialize(data, node$con, xdr = FALSE): 'package:variancePartition'
## may not be available when loading

## Warning in serialize(data, node$con, xdr = FALSE): 'package:variancePartition'
## may not be available when loading

## Warning in serialize(data, node$con, xdr = FALSE): 'package:variancePartition'
## may not be available when loading

## Warning in serialize(data, node$con, xdr = FALSE): 'package:variancePartition'
## may not be available when loading

## Warning in serialize(data, node$con, xdr = FALSE): 'package:variancePartition'
## may not be available when loading

## Warning in serialize(data, node$con, xdr = FALSE): 'package:variancePartition'
## may not be available when loading

## Warning in serialize(data, node$con, xdr = FALSE): 'package:variancePartition'
## may not be available when loading

## Warning in serialize(data, node$con, xdr = FALSE): 'package:variancePartition'
## may not be available when loading

## Warning in serialize(data, node$con, xdr = FALSE): 'package:variancePartition'
## may not be available when loading

## Warning in serialize(data, node$con, xdr = FALSE): 'package:variancePartition'
## may not be available when loading

## Warning in serialize(data, node$con, xdr = FALSE): 'package:variancePartition'
## may not be available when loading

## Warning in serialize(data, node$con, xdr = FALSE): 'package:variancePartition'
## may not be available when loading

## Warning in serialize(data, node$con, xdr = FALSE): 'package:variancePartition'
## may not be available when loading

## Warning in serialize(data, node$con, xdr = FALSE): 'package:variancePartition'
## may not be available when loading

## Warning in serialize(data, node$con, xdr = FALSE): 'package:variancePartition'
## may not be available when loading

## Warning in serialize(data, node$con, xdr = FALSE): 'package:variancePartition'
## may not be available when loading

## Warning in serialize(data, node$con, xdr = FALSE): 'package:variancePartition'
## may not be available when loading

## Warning in serialize(data, node$con, xdr = FALSE): 'package:variancePartition'
## may not be available when loading

## Warning in serialize(data, node$con, xdr = FALSE): 'package:variancePartition'
## may not be available when loading

## Warning in serialize(data, node$con, xdr = FALSE): 'package:variancePartition'
## may not be available when loading

## Warning in serialize(data, node$con, xdr = FALSE): 'package:variancePartition'
## may not be available when loading

## Warning in serialize(data, node$con, xdr = FALSE): 'package:variancePartition'
## may not be available when loading

## Warning in serialize(data, node$con, xdr = FALSE): 'package:variancePartition'
## may not be available when loading

## Warning in serialize(data, node$con, xdr = FALSE): 'package:variancePartition'
## may not be available when loading

## Warning in serialize(data, node$con, xdr = FALSE): 'package:variancePartition'
## may not be available when loading

## Warning in serialize(data, node$con, xdr = FALSE): 'package:variancePartition'
## may not be available when loading

## Warning in serialize(data, node$con, xdr = FALSE): 'package:variancePartition'
## may not be available when loading

## Warning in serialize(data, node$con, xdr = FALSE): 'package:variancePartition'
## may not be available when loading

## Warning in serialize(data, node$con, xdr = FALSE): 'package:variancePartition'
## may not be available when loading

## Warning in serialize(data, node$con, xdr = FALSE): 'package:variancePartition'
## may not be available when loading

## Warning in serialize(data, node$con, xdr = FALSE): 'package:variancePartition'
## may not be available when loading

## Warning in serialize(data, node$con, xdr = FALSE): 'package:variancePartition'
## may not be available when loading

## Warning in serialize(data, node$con, xdr = FALSE): 'package:variancePartition'
## may not be available when loading

## Warning in serialize(data, node$con, xdr = FALSE): 'package:variancePartition'
## may not be available when loading

## Warning in serialize(data, node$con, xdr = FALSE): 'package:variancePartition'
## may not be available when loading

## Warning in serialize(data, node$con, xdr = FALSE): 'package:variancePartition'
## may not be available when loading

## Warning in serialize(data, node$con, xdr = FALSE): 'package:variancePartition'
## may not be available when loading

## Warning in serialize(data, node$con, xdr = FALSE): 'package:variancePartition'
## may not be available when loading

## Warning in serialize(data, node$con, xdr = FALSE): 'package:variancePartition'
## may not be available when loading

## Warning in serialize(data, node$con, xdr = FALSE): 'package:variancePartition'
## may not be available when loading

## Warning in serialize(data, node$con, xdr = FALSE): 'package:variancePartition'
## may not be available when loading

## Warning in serialize(data, node$con, xdr = FALSE): 'package:variancePartition'
## may not be available when loading

## Warning in serialize(data, node$con, xdr = FALSE): 'package:variancePartition'
## may not be available when loading

## Warning in serialize(data, node$con, xdr = FALSE): 'package:variancePartition'
## may not be available when loading

## Warning in serialize(data, node$con, xdr = FALSE): 'package:variancePartition'
## may not be available when loading

## Warning in serialize(data, node$con, xdr = FALSE): 'package:variancePartition'
## may not be available when loading

## Warning in serialize(data, node$con, xdr = FALSE): 'package:variancePartition'
## may not be available when loading

## Warning in serialize(data, node$con, xdr = FALSE): 'package:variancePartition'
## may not be available when loading

## Warning in serialize(data, node$con, xdr = FALSE): 'package:variancePartition'
## may not be available when loading

## Warning in serialize(data, node$con, xdr = FALSE): 'package:variancePartition'
## may not be available when loading

## Warning in serialize(data, node$con, xdr = FALSE): 'package:variancePartition'
## may not be available when loading

## Warning in serialize(data, node$con, xdr = FALSE): 'package:variancePartition'
## may not be available when loading

## Warning in serialize(data, node$con, xdr = FALSE): 'package:variancePartition'
## may not be available when loading

## Warning in serialize(data, node$con, xdr = FALSE): 'package:variancePartition'
## may not be available when loading

## Warning in serialize(data, node$con, xdr = FALSE): 'package:variancePartition'
## may not be available when loading

## Warning in serialize(data, node$con, xdr = FALSE): 'package:variancePartition'
## may not be available when loading

## Warning in serialize(data, node$con, xdr = FALSE): 'package:variancePartition'
## may not be available when loading

## Warning in serialize(data, node$con, xdr = FALSE): 'package:variancePartition'
## may not be available when loading

## Warning in serialize(data, node$con, xdr = FALSE): 'package:variancePartition'
## may not be available when loading

## Warning in serialize(data, node$con, xdr = FALSE): 'package:variancePartition'
## may not be available when loading

## Warning in serialize(data, node$con, xdr = FALSE): 'package:variancePartition'
## may not be available when loading

## Warning in serialize(data, node$con, xdr = FALSE): 'package:variancePartition'
## may not be available when loading

## Warning in serialize(data, node$con, xdr = FALSE): 'package:variancePartition'
## may not be available when loading

## Warning in serialize(data, node$con, xdr = FALSE): 'package:variancePartition'
## may not be available when loading

## Warning in serialize(data, node$con, xdr = FALSE): 'package:variancePartition'
## may not be available when loading

## Warning in serialize(data, node$con, xdr = FALSE): 'package:variancePartition'
## may not be available when loading

## Warning in serialize(data, node$con, xdr = FALSE): 'package:variancePartition'
## may not be available when loading

## Warning in serialize(data, node$con, xdr = FALSE): 'package:variancePartition'
## may not be available when loading

## Warning in serialize(data, node$con, xdr = FALSE): 'package:variancePartition'
## may not be available when loading

## Warning in serialize(data, node$con, xdr = FALSE): 'package:variancePartition'
## may not be available when loading

## Warning in serialize(data, node$con, xdr = FALSE): 'package:variancePartition'
## may not be available when loading

## Warning in serialize(data, node$con, xdr = FALSE): 'package:variancePartition'
## may not be available when loading

## Warning in serialize(data, node$con, xdr = FALSE): 'package:variancePartition'
## may not be available when loading

## Warning in serialize(data, node$con, xdr = FALSE): 'package:variancePartition'
## may not be available when loading

## Warning in serialize(data, node$con, xdr = FALSE): 'package:variancePartition'
## may not be available when loading

## Warning in serialize(data, node$con, xdr = FALSE): 'package:variancePartition'
## may not be available when loading

## Warning in serialize(data, node$con, xdr = FALSE): 'package:variancePartition'
## may not be available when loading

## Warning in serialize(data, node$con, xdr = FALSE): 'package:variancePartition'
## may not be available when loading

## Warning in serialize(data, node$con, xdr = FALSE): 'package:variancePartition'
## may not be available when loading

## Warning in serialize(data, node$con, xdr = FALSE): 'package:variancePartition'
## may not be available when loading
## 
## Total:22 s
## Placing factor: condition at the beginning of the model.
test_varpart$percent_plot

test_varpart$partition_plot

## Here, let us test the variance contributed by strain, time, and replicate.
test_varpart <- simple_varpart(fission_expt, predictor=NULL, factors=c("condition", "strain", "minute", "replicate"))
## Attempting mixed linear model with: ~  (1|condition) + (1|strain) + (1|minute) + (1|replicate)
## Fitting the expressionset to the model, this is slow.
## Dividing work into 100 chunks...
## 
## Total:27 s
## Placing factor: condition at the beginning of the model.
test_varpart$percent_plot

test_varpart$partition_plot

YAY!

pander::pander(sessionInfo())

R version 3.6.1 (2019-07-05)

Platform: x86_64-pc-linux-gnu (64-bit)

locale: LC_CTYPE=en_US.UTF-8, LC_NUMERIC=C, LC_TIME=en_US.UTF-8, LC_COLLATE=en_US.UTF-8, LC_MONETARY=en_US.UTF-8, LC_MESSAGES=en_US.UTF-8, LC_PAPER=en_US.UTF-8, LC_NAME=C, LC_ADDRESS=C, LC_TELEPHONE=C, LC_MEASUREMENT=en_US.UTF-8 and LC_IDENTIFICATION=C

attached base packages: stats4, parallel, stats, graphics, grDevices, utils, datasets, methods and base

other attached packages: variancePartition(v.1.16.1), fission(v.1.6.0), ruv(v.0.9.7.1), SummarizedExperiment(v.1.16.1), DelayedArray(v.0.12.2), BiocParallel(v.1.20.1), matrixStats(v.0.55.0), GenomicRanges(v.1.38.0), GenomeInfoDb(v.1.22.0), IRanges(v.2.20.2), S4Vectors(v.0.24.3), hpgltools(v.1.0), Biobase(v.2.46.0) and BiocGenerics(v.0.32.0)

loaded via a namespace (and not attached): R.utils(v.2.9.2), tidyselect(v.1.0.0), lme4(v.1.1-21), RSQLite(v.2.2.0), AnnotationDbi(v.1.48.0), htmlwidgets(v.1.5.1), grid(v.3.6.1), Rtsne(v.0.15), devtools(v.2.2.2), DESeq(v.1.38.0), munsell(v.0.5.0), codetools(v.0.2-16), preprocessCore(v.1.48.0), withr(v.2.1.2), colorspace(v.1.4-1), highr(v.0.8), knitr(v.1.28), rstudioapi(v.0.11), Vennerable(v.3.1.0.9000), robustbase(v.0.93-5), genoPlotR(v.0.8.9), labeling(v.0.3), GenomeInfoDbData(v.1.2.2), bit64(v.0.9-7), farver(v.2.0.3), rprojroot(v.1.3-2), vctrs(v.0.2.4), xfun(v.0.12), fastcluster(v.1.1.25), R6(v.2.4.1), doParallel(v.1.0.15), locfit(v.1.5-9.1), bitops(v.1.0-6), assertthat(v.0.2.1), promises(v.1.1.0), scales(v.1.1.0), nnet(v.7.3-12), gtable(v.0.3.0), sva(v.3.34.0), processx(v.3.4.2), rlang(v.0.4.5), genefilter(v.1.68.0), splines(v.3.6.1), rtracklayer(v.1.46.0), lazyeval(v.0.2.2), acepack(v.1.4.1), selectr(v.0.4-2), checkmate(v.2.0.0), yaml(v.2.2.1), reshape2(v.1.4.3), crosstalk(v.1.0.0), backports(v.1.1.5), httpuv(v.1.5.2), Hmisc(v.4.3-1), RBGL(v.1.62.1), tools(v.3.6.1), usethis(v.1.5.1), ggplot2(v.3.2.1), ellipsis(v.0.3.0), gplots(v.3.0.1.2), RColorBrewer(v.1.1-2), sessioninfo(v.1.1.1), Rcpp(v.1.0.3), plyr(v.1.8.5), progress(v.1.2.2), base64enc(v.0.1-3), zlibbioc(v.1.32.0), purrr(v.0.3.3), RCurl(v.1.98-1.1), ps(v.1.3.2), prettyunits(v.1.1.1), rpart(v.4.1-15), ggrepel(v.0.8.1), cluster(v.2.1.0), colorRamps(v.2.3), fs(v.1.3.1), magrittr(v.1.5), data.table(v.1.12.8), openxlsx(v.4.1.4), pkgload(v.1.0.2), hms(v.0.5.3), mime(v.0.9), evaluate(v.0.14), xtable(v.1.8-4), pbkrtest(v.0.4-7), XML(v.3.99-0.3), jpeg(v.0.1-8.1), gridExtra(v.2.3), testthat(v.2.3.1), compiler(v.3.6.1), tibble(v.2.1.3), KernSmooth(v.2.23-16), crayon(v.1.3.4), minqa(v.1.2.4), R.oo(v.1.23.0), htmltools(v.0.4.0), mgcv(v.1.8-31), corpcor(v.1.6.9), later(v.1.0.0), Formula(v.1.2-3), tidyr(v.1.0.2), geneplotter(v.1.64.0), DBI(v.1.1.0), MASS(v.7.3-51.5), boot(v.1.3-24), Matrix(v.1.2-18), ade4(v.1.7-15), readr(v.1.3.1), cli(v.2.0.1), quadprog(v.1.5-8), R.methodsS3(v.1.8.0), gdata(v.2.18.0), pkgconfig(v.2.0.3), GenomicAlignments(v.1.22.1), foreign(v.0.8-75), plotly(v.4.9.2), xml2(v.1.2.2), foreach(v.1.4.8), annotate(v.1.64.0), XVector(v.0.26.0), rvest(v.0.3.5), stringr(v.1.4.0), callr(v.3.4.2), digest(v.0.6.25), graph(v.1.64.0), Biostrings(v.2.54.0), rmarkdown(v.2.1), htmlTable(v.1.13.3), edgeR(v.3.28.0), directlabels(v.2020.1.31), curl(v.4.3), shiny(v.1.4.0), Rsamtools(v.2.2.2), gtools(v.3.8.1), nloptr(v.1.2.1), lifecycle(v.0.1.0), nlme(v.3.1-144), jsonlite(v.1.6.1), desc(v.1.2.0), viridisLite(v.0.3.0), limma(v.3.42.2), fansi(v.0.4.1), pillar(v.1.4.3), lattice(v.0.20-40), fastmap(v.1.0.1), httr(v.1.4.1), DEoptimR(v.1.0-8), pkgbuild(v.1.0.6), survival(v.3.1-8), glue(v.1.3.1), remotes(v.2.1.1), zip(v.2.0.4), png(v.0.1-7), iterators(v.1.0.12), pander(v.0.6.3), bit(v.1.1-15.2), stringi(v.1.4.6), blob(v.1.2.1), DESeq2(v.1.26.0), latticeExtra(v.0.6-29), caTools(v.1.18.0), memoise(v.1.1.0) and dplyr(v.0.8.4)

LS0tCnRpdGxlOiAiaHBnbHRvb2xzIGV4YW1wbGVzIHVzaW5nIHRoZSBmaXNzaW9uIGRhdGFzZXQiCmF1dGhvcjogImF0YiBhYmVsZXdAZ21haWwuY29tIgpkYXRlOiAiYHIgU3lzLkRhdGUoKWAiCm91dHB1dDoKIGh0bWxfZG9jdW1lbnQ6CiAgY29kZV9kb3dubG9hZDogdHJ1ZQogIGNvZGVfZm9sZGluZzogc2hvdwogIGZpZ19jYXB0aW9uOiB0cnVlCiAgZmlnX2hlaWdodDogNwogIGZpZ193aWR0aDogNwogIGhpZ2hsaWdodDogZGVmYXVsdAogIGtlZXBfbWQ6IGZhbHNlCiAgbW9kZTogc2VsZmNvbnRhaW5lZAogIG51bWJlcl9zZWN0aW9uczogdHJ1ZQogIHNlbGZfY29udGFpbmVkOiB0cnVlCiAgdGhlbWU6IHJlYWRhYmxlCiAgdG9jOiB0cnVlCiAgdG9jX2Zsb2F0OgogICAgY29sbGFwc2VkOiBmYWxzZQogICAgc21vb3RoX3Njcm9sbDogZmFsc2UKdmlnbmV0dGU6ID4KICAlXFZpZ25ldHRlSW5kZXhFbnRyeXtiLTAyX2Zpc3Npb25fZGF0YV9leHBsb3JhdGlvbn0KICAlXFZpZ25ldHRlRW5naW5le2tuaXRyOjpybWFya2Rvd259CiAgXHVzZXBhY2thZ2VbdXRmOF17aW5wdXRlbmN9Ci0tLQoKYGBge3Igb3B0aW9ucywgaW5jbHVkZT1GQUxTRX0KIyMgVGhlc2UgYXJlIHRoZSBvcHRpb25zIEkgdGVuZCB0byBmYXZvcgpsaWJyYXJ5KCJocGdsdG9vbHMiKQprbml0cjo6b3B0c19rbml0JHNldChwcm9ncmVzcz1UUlVFLAogICAgICAgICAgICAgICAgICAgICB2ZXJib3NlPVRSVUUsCiAgICAgICAgICAgICAgICAgICAgIHdpZHRoPTkwLAogICAgICAgICAgICAgICAgICAgICBlY2hvPVRSVUUpCmtuaXRyOjpvcHRzX2NodW5rJHNldChlcnJvcj1UUlVFLAogICAgICAgICAgICAgICAgICAgICAgZmlnLndpZHRoPTgsCiAgICAgICAgICAgICAgICAgICAgICBmaWcuaGVpZ2h0PTgsCiAgICAgICAgICAgICAgICAgICAgICBkcGk9OTYpCm9sZF9vcHRpb25zIDwtIG9wdGlvbnMoZGlnaXRzPTQsCiAgICAgICAgICAgICAgICAgICAgICAgc3RyaW5nc0FzRmFjdG9ycz1GQUxTRSwKICAgICAgICAgICAgICAgICAgICAgICBrbml0ci5kdXBsaWNhdGUubGFiZWw9ImFsbG93IikKZ2dwbG90Mjo6dGhlbWVfc2V0KGdncGxvdDI6OnRoZW1lX2J3KGJhc2Vfc2l6ZT0xMCkpCnNldC5zZWVkKDEpCnJtZF9maWxlIDwtICJiLTAyX2Zpc3Npb25fZGF0YV9leHBsb3JhdGlvbi5SbWQiCmBgYAoKIyBFeGFtcGxlIGhwZ2x0b29sIHVzYWdlIHdpdGggYSByZWFsIGRhdGEgc2V0IChmaXNzaW9uKQoKVGhpcyBkb2N1bWVudCBhaW1zIHRvIHByb3ZpZGUgZnVydGhlciBleGFtcGxlcyBpbiBob3cgdG8gdXNlIHRoZSBocGdsdG9vbHMuCgpOb3RlIHRvIHNlbGYsIHRoZSBoZWFkZXIgaGFzIHJtYXJrZG93bjo6cGRmX2RvY3VtZW50IGluc3RlYWQgb2YgaHRtbF9kb2N1bWVudCBvciBodG1sX3ZpZ25ldHRlCmJlY2F1c2UgaXQgZ2V0cyBzb21lIGJ1bGxjcmFwIGVycm9yICdtYXJnaW5zIHRvbyBsYXJnZScuLi4KCiMjIFNldHRpbmcgdXAKCkhlcmUgYXJlIHRoZSBjb21tYW5kcyBJIGludm9rZSB0byBnZXQgcmVhZHkgdG8gcGxheSB3aXRoIG5ldyBkYXRhLCBpbmNsdWRpbmcgZXZlcnl0aGluZwpyZXF1aXJlZCB0byBpbnN0YWxsIGhwZ2x0b29scywgdGhlIHNvZnR3YXJlIGl0IHVzZXMsIGFuZCB0aGUgZmlzc2lvbiBkYXRhLgoKYGBge3Igc2V0dXB9CmlmICghICJCaW9jTWFuYWdlciIgJWluJSBpbnN0YWxsZWQucGFja2FnZXMoKSkgewogIHNvdXJjZSgiaHR0cDovL2Jpb2NvbmR1Y3Rvci5vcmcvYmlvY0xpdGUuUiIpCn0KaWYgKCEgImRldnRvb2xzIiAlaW4lIGluc3RhbGxlZC5wYWNrYWdlcygpKSB7CiAgYmlvY01hbmFnZXI6Omluc3RhbGwoImRldnRvb2xzIikKfQppZiAoISAiaHBnbHRvb2xzIiAlaW4lIGluc3RhbGxlZC5wYWNrYWdlcygpKSB7CiAgZGV2dG9vbHM6Omluc3RhbGxfZ2l0aHViKCJlbHNheWVkLWxhYi9ocGdsdG9vbHMiKQp9CmlmICghICJmaXNzaW9uIiAlaW4lIGluc3RhbGxlZC5wYWNrYWdlcygpKSB7CiAgYmlvY01hbmFnZXI6Omluc3RhbGwoImZpc3Npb24iKQp9CiMjIEkgdXNlIHRoZSBmdW5jdGlvbiAnc20oKScgdG8gcXVpZXQgbG91ZCBmdW5jdGlvbnMuCnR0IDwtIHNtKGxpYnJhcnkoZmlzc2lvbikpCnR0IDwtIHNtKGRhdGEoZmlzc2lvbikpCmBgYAoKIyMgRGF0YSBpbXBvcnQKCkFsbCB0aGUgd29yayBJIGRvIGluIERyLiBFbC1TYXllZCdzIGxhYiBtYWtlcyBzb21lIHByZXR0eSBoYXJkCmFzc3VtcHRpb25zIGFib3V0IGhvdyBkYXRhIGlzIHN0b3JlZC4gIEFzIGEgcmVzdWx0LCB0byB1c2UgdGhlIGZpc3Npb24KZGF0YSBzZXQgSSB3aWxsIGRvIGEgbGl0dGxlIGJpdCBvZiBzaGVuYW5pZ2FucyB0byBtYXRjaCBpdCB0byB0aGUKZXhwZWN0ZWQgZm9ybWF0LiAgTm93IHRoYXQgSSBoYXZlIHBsYXllZCBhIGxpdHRsZSB3aXRoIGZpc3Npb24sIEkKdGhpbmsgaXRzIGZvcm1hdCBpcyBxdWl0ZSBuaWNlIGFuZCBhbSBsaWtlbHkgdG8gaGF2ZSBteSBleHBlcmltZW50CmNsYXNzIGluc3RlYWQgYmUgYSBTdW1tYXJpemVkRXhwZXJpbWVudC4KCmBgYHtyIGRhdGFfaW1wb3J0fQojIyBFeHRyYWN0IHRoZSBtZXRhIGRhdGEgZnJvbSB0aGUgZmlzc2lvbiBkYXRhc2V0Cm1ldGEgPC0gYXMuZGF0YS5mcmFtZShmaXNzaW9uQGNvbERhdGEpCiMjIE1ha2UgY29uZGl0aW9ucyBhbmQgYmF0Y2hlcwptZXRhJGNvbmRpdGlvbiA8LSBwYXN0ZShtZXRhJHN0cmFpbiwgbWV0YSRtaW51dGUsIHNlcD0iLiIpCm1ldGEkYmF0Y2ggPC0gbWV0YSRyZXBsaWNhdGUKbWV0YSRzYW1wbGUuaWQgPC0gcm93bmFtZXMobWV0YSkKIyMgR3JhYiB0aGUgY291bnQgZGF0YQpmaXNzaW9uX2RhdGEgPC0gZmlzc2lvbkBhc3NheXMkZGF0YSRjb3VudHMKIyMgVGhpcyB3aWxsIG1ha2UgYW4gZXhwZXJpbWVudCBzdXBlcmNsYXNzIGNhbGxlZCAnZXhwdCcgYW5kIGl0IGNvbnRhaW5zCiMjIGFuIEV4cHJlc3Npb25TZXQgYWxvbmcgd2l0aCBhbnkgYXJiaXRyYXJ5IGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gb25lIG1pZ2h0IHdhbnQgdG8gaW5jbHVkZS4KIyMgQWxvbmcgdGhlIHdheSBpdCB3cml0ZXMgYSBSZGF0YSBmaWxlIHdoaWNoIGlzIGJ5IGRlZmF1bHQgY2FsbGVkICdleHB0LlJkYXRhJwpmaXNzaW9uX2V4cHQgPC0gY3JlYXRlX2V4cHQobWV0YWRhdGE9bWV0YSwgY291bnRfZGF0YWZyYW1lPWZpc3Npb25fZGF0YSkKYGBgCgojIyBOb3JtYWxpemluZyBhbmQgZXhwbG9yaW5nIGRhdGEKClRoZXJlIGFyZSBsb3RzIG9mIHRveXMgd2UgaGF2ZSBsZWFybmVkIHRvIHVzZSB0byBwbGF5IHdpdGggd2l0aCByYXcKZGF0YSBhbmQgZXhwbG9yZSBzdHVmZiBsaWtlIGJhdGNoIGVmZmVjdHMgb3Igbm9uLWNhbm9uaWNhbApkaXN0cmlidXRpb25zIG9yIHNrZXdlZCBjb3VudHMuICBocGdsdG9vbHMgcHJvdmlkZXMgc29tZSBmdW5jdGlvbmFsaXR5CnRvIG1ha2UgdGhpcyBwcm9jZXNzIGVhc2llci4gIFRoZSBncmFwaHMgc2hvd24gYmVsb3cgYW5kIG1hbnkgbW9yZSBhcmUKZ2VuZXJhdGVkIHdpdGggdGhlIHdyYXBwZXIgJ2dyYXBoX21ldHJpY3MoKScgYnV0IHRoYXQgdGFrZXMgYXdheSB0aGUKY2hhbmNlIHRvIGV4cGxhaW4gdGhlIGdyYXBocyBhcyBJIGdlbmVyYXRlIHRoZW0uCgpgYGB7ciBub3JtX2V4cGxvcmV9CiMjIEZpcnN0IG1ha2UgYSBiYXIgcGxvdCBvZiB0aGUgbGlicmFyeSBzaXplcyBpbiB0aGUgZXhwZXJpbWVudC4KIyMgTm90aWNlIHRoYXQgdGhlIGNvbG9ycyB3ZXJlIGF1dG8tY2hvc2VuIGJ5IGNyZWF0ZV9leHB0KCkgYW5kIHRoZXkgc2hvdWxkCiMjIGJlIG1haW50YWluZWQgdGhyb3VnaG91dCB0aGlzIHByb2Nlc3MKZmlzX2xpYnNpemUgPC0gcGxvdF9saWJzaXplKGZpc3Npb25fZXhwdCkKZmlzX2xpYnNpemUkcGxvdAojIyBIZXJlIHdlIHNlZSB0aGF0IHRoZSB3aWxkIHR5cGUgcmVwbGljYXRlIDMgc2FtcGxlIGZvciAxNSBtaW51dGVzIGhhcyBmZXdlciBub24temVybyBnZW5lcyB0aGFuIGFsbCBpdHMgZnJpZW5kcy4KZmlzX25vbnplcm8gPC0gcGxvdF9ub256ZXJvKGZpc3Npb25fZXhwdCwgbGFiZWxzPSJib3JpbmciLCB0aXRsZT0ibm9uemVybyB2cy4gY3BtIikKZmlzX25vbnplcm8kcGxvdAoKZmlzX2RlbnNpdHkgPC0gcGxvdF9kZW5zaXR5KGZpc3Npb25fZXhwdCkKZmlzX2RlbnNpdHkkcGxvdAprbml0cjo6a2FibGUoZmlzX2RlbnNpdHkkY29uZGl0aW9uX3N1bW1hcnkpCmtuaXRyOjprYWJsZShmaXNfZGVuc2l0eSRiYXRjaF9zdW1tYXJ5KQprbml0cjo6a2FibGUoaGVhZChmaXNfZGVuc2l0eSRzYW1wbGVfc3VtbWFyeSkpCmBgYAoKIyMjIEFuIGluaXRpYWwgcGNhIHBsb3QKCkluIG1vc3QgY2FzZXMsIHJhdyBkYXRhIGRvZXMgbm90IGNsdXN0ZXIgdmVyeSB3ZWxsLCBsZXRzIHNlZSBpZiB0aGF0CmlzIGFsc28gdHJ1ZSBmb3IgdGhlIGZpc3Npb24gZXhwZXJpbWVudC4gQXNzdW1pbmcgaXQgZG9lc24ndCwgbGV0cwpub3JtYWxpemUgdGhlIGRhdGEgdXNpbmcgdGhlIGRlZmF1bHRzIChjcG0sIHF1YW50aWxlLCBsb2cyKSBhbmQgdHJ5CmFnYWluLgoKYGBge3IgcGNhfQojIyBTb21ldGhpbmcgaW4gdGhpcyBpcyBjYXVzaW5nIGEgYnVpbGQgbG9vcCBvbiB0cmF2aXMuLi4KIyMgVW5zdXJwcmlzaW5nbHksIHRoZSByYXcgZGF0YSBkb2Vzbid0IGNsdXN0ZXIgd2VsbCBhdCBhbGwuLi4KIyNmaXNfcmF3cGNhIDwtIHBsb3RfcGNhKGZpc3Npb25fZXhwdCwgZXhwdF9uYW1lcz1maXNzaW9uX2V4cHQkY29uZGl0aW9uLCBjaXM9TlVMTCkKZmlzX3Jhd3BjYSA8LSBwbG90X3BjYShmaXNzaW9uX2V4cHQpCmZpc19yYXdwY2EkcGxvdAojIyBTbywgbm9ybWFsaXplIHRoZSBkYXRhCm5vcm1fZXhwdCA8LSBzbShub3JtYWxpemVfZXhwdChmaXNzaW9uX2V4cHQsIHRyYW5zZm9ybT0ibG9nMiIsIG5vcm09InF1YW50IiwgY29udmVydD0iY3BtIikpCiMjIEFuZCB0cnkgdGhlIHBjYSBhZ2FpbgpmaXNfbm9ybXBjYSA8LSBwbG90X3BjYShub3JtX2V4cHQsIHBsb3RfbGFiZWxzPSJub3JtYWwiLCB0aXRsZT0ibm9ybWFsaXplZCBwY2EiLCBjaXM9TlVMTCkKZmlzX25vcm1wY2EkcGxvdAojIyBDbGVhcmx5IHRpbWUgaXMgYW4gaW1wb3J0YW50IGZhY3RvciBpbiB0aGUgZGF0YS4KYGBgCgojIyBUcnkgc29tZXRoaW5nIGZvciBOYWppYgoKYGBge3IgdGVzdF8zZH0KdGVzdGluZyA8LSBwbG90X3BjYShub3JtX2V4cHQsIG51bV9wYz0zKQpzaWxseSA8LSBwbG90XzNkX3BjYSh0ZXN0aW5nKQpzaWxseSRwbG90CmBgYAoKSW4gdGhlIGZpbmFsIGxpbmUgb2YgdGhlIHByZWNlZWRpbmcgYmxvY2ssIEkgcHJpbnRlZCBhIHN1bW1hcnkgb2YgdGhlIHJldHVybiBmcm9tIHBsb3RfcGNhKCkuCkl0IGNvbnRhaW5zIHRoZSBmb2xsb3dpbmcgaW5mb3JtYXRpb246CgoqIHBjYTogICAgICBUaGUgcmVzdWx0IGZyb20gdGhlIGZhc3Quc3ZkKCkgY2FsbC4KKiBwbG90OiAgICAgVGhlIGdncGxvdDIgcGNhIHBsb3QuCiogdGFibGU6ICAgIFRoZSBtZXRhZGF0YSB1c2VkIHRvIG1ha2UgdGhlIHBjYSBwbG90LgoqIHJlczogICAgICBBIHRhYmxlIG9mIHRoZSByZXNpZHVhbCB2YXJpYW5jZSBhZnRlciBlYWNoIGNvbXBvbmVudCBieSBjb25kaXRpb24vYmF0Y2guCiogdmFyaWFuY2U6IEEgbnVtZXJpYyBsaXN0IG9mIHRoZSAldmFyaWFuY2UgcmVtYWluaW5nIGFmdGVyIGVhY2ggUEMuCgpXaXRoIHRoYXQgaW4gbWluZCwgbGV0cyBwZXJmb3JtIHNvbWUgbW9yZSBwY2EgcGxvdHMgYWZ0ZXIgbm9ybWFsaXppbmcgdGhlIGRhdGEgYW5kIHNlZSBob3cgZGlmZmVyZW50CnRoZXkgbG9vay4KCmBgYHtyIG5vcm1hbGl6ZWRfcGNhfQpub3JtYmF0Y2hfZXhwdCA8LSBzbShub3JtYWxpemVfZXhwdChmaXNzaW9uX2V4cHQsIHRyYW5zZm9ybT0ibG9nMiIsIG5vcm09InF1YW50IiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29udmVydD0iY3BtIiwgYmF0Y2g9InN2YSIpKQpmaXNfbm9ybWJhdGNocGNhIDwtIHBsb3RfcGNhKG5vcm1iYXRjaF9leHB0LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRpdGxlPSJOb3JtYWxpemVkIFBDQSB3aXRoIGJhdGNoIGVmZmVjdCBjb3JyZWN0aW9uLiIsIGNpcz1OVUxMKQpmaXNfbm9ybWJhdGNocGNhJHBsb3QKIyMgb2ssIHRoYXQgY2F1c2VkIHRoZSAwLCA2MCwgMTUsIGFuZCAzMCBtaW51dGUgc2FtcGxlcyB0byBjbHVzdGVyIG5pY2VseQojIyB0aGUgMTIwIGFuZCAxODAgbWludXRlIHNhbXBsZXMgYXJlIHN0aWxsIGEgYml0IHRpZ2h0CgojIyBwY2FfaW5mb3JtYXRpb24gcHJvdmlkZXMgc29tZSBtb3JlIGluZm9ybWF0aW9uIGFib3V0IHRoZSBjYWxsIHRvCiMjIGZhc3Quc3ZkIHRoYXQgd2VudCBpbnRvIG1ha2luZyB0aGUgcGNhIHBsb3QKZmlzX2luZm8gPC0gcGNhX2luZm9ybWF0aW9uKG5vcm1fZXhwdCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGV4cHRfZmFjdG9ycz1jKCJjb25kaXRpb24iLCJiYXRjaCIsInN0cmFpbiIsIm1pbnV0ZSIpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgbnVtX2NvbXBvbmVudHM9NikKIyMgVGhlIHJeMiB0YWJsZSBzaG93cyB0aGF0IHF1aXRlIGEgbG90IG9mIHRoZSB2YXJpYW5jZSBpbiB0aGUgZGF0YSBpcyBleHBsYWluZWQgYnkgY29uZGl0aW9uCmtuaXRyOjprYWJsZShoZWFkKGZpc19pbmZvJHJzcXVhcmVkX3RhYmxlKSkKIyMgV2UgY2FuIGxvb2sgYXQgdGhlIGNvcnJlbGF0aW9uIGJldHdlZW4gdGhlIHByaW5jaXBsZSBjb21wb25lbnRzIGFuZCB0aGUgZmFjdG9ycyBpbiB0aGUgZXhwZXJpbWVudAojIyBpbiB0aGlzIGNhc2UgbG9va2luZyBhdCBjb25kaXRpb24vYmF0Y2ggdnMgdGhlIGZpcnN0IDQgY29tcG9uZW50cy4Ka25pdHI6OmthYmxlKGZpc19pbmZvJHBjYV9jb3IpCiMjIEFuZCBwLXZhbHVlcyB0byBsZW5kIHNvbWUgY3JlZGVuY2Uob3Igbm90IHRvIHRob3NlIGFzc2VydGlvbnMpCmtuaXRyOjprYWJsZShmaXNfaW5mbyRhbm92YV9wKQoKIyMgVHJ5IGFnYWluIHdpdGggYmF0Y2ggcmVtb3ZlZCBkYXRhCmJhdGNobm9ybV9leHB0IDwtIHNtKG5vcm1hbGl6ZV9leHB0KGZpc3Npb25fZXhwdCwgYmF0Y2g9ImxpbW1hIiwgbm9ybT0icXVhbnQiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0cmFuc2Zvcm09ImxvZzIiLCBjb252ZXJ0PSJjcG0iKSkKZmlzX2JhdGNobm9ybXBjYSA8LSBwbG90X3BjYShiYXRjaG5vcm1fZXhwdCwgcGxvdF90aXRsZT0ibGltbWEgY29ycmVjdGVkIHBjYSIpCmZpc19iYXRjaG5vcm1wY2EkcGxvdAp0ZXN0X3BjYSA8LSBwY2FfaW5mb3JtYXRpb24oYmF0Y2hub3JtX2V4cHQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBleHB0X2ZhY3RvcnM9YygiY29uZGl0aW9uIiwiYmF0Y2giLCJzdHJhaW4iLCJtaW51dGUiKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgIG51bV9jb21wb25lbnRzPTYpCmBgYAoKSW50ZXJlc3RpbmcsIHRoZSBiYXRjaCBub3JtYWxpemVkIHBjYSBwbG90IGxvb2tzIG11Y2ggdGhlIHNhbWUgYXMgdGhlCm5vcm1hbGl6ZWQuIFRoZSB2YXJpYW5jZXMgYXJlIGluIGZhY3QgcHJldHR5IG11Y2ggdGhlIGV4YWN0IHNhbWUuLi4KCiMjIExvb2sgYXQgdGhlIGRhdGEgZGlzdHJpYnV0aW9ucwoKV2UgaGF2ZSBzb21lIHRvb2xzIHdoaWNoIHByb3ZpZGUgdmlzdWFsaXphdGlvbnMgb2YgdGhlIGRpc3RyaWJ1dGlvbiBvZgp0aGUgZGF0YToKCmBgYHtyIGRpc3RyaWJ1dGlvbnN9CmZpc3Npb25fYm94cGxvdCA8LSBzbShwbG90X2JveHBsb3QoZmlzc2lvbl9leHB0KSkKZmlzc2lvbl9ib3hwbG90CnNmX2V4cHQgPC0gc20obm9ybWFsaXplX2V4cHQoZmlzc2lvbl9leHB0LCBub3JtPSJzZiIpKQpmaXNzaW9uX2JveHBsb3QgPC0gc20ocGxvdF9ib3hwbG90KHNmX2V4cHQpKQpmaXNzaW9uX2JveHBsb3QKdG1fZXhwdCA8LSBzbShub3JtYWxpemVfZXhwdChmaXNzaW9uX2V4cHQsIG5vcm09InRtbSIpKQpmaXNzaW9uX2JveHBsb3QgPC0gc20ocGxvdF9ib3hwbG90KHRtX2V4cHQpKQpmaXNzaW9uX2JveHBsb3QKcmxlX2V4cHQgPC0gc20obm9ybWFsaXplX2V4cHQoZmlzc2lvbl9leHB0LCBub3JtPSJybGUiKSkKZmlzc2lvbl9ib3hwbG90IDwtIHNtKHBsb3RfYm94cGxvdChybGVfZXhwdCkpCmZpc3Npb25fYm94cGxvdAp1cF9leHB0IDwtIHNtKG5vcm1hbGl6ZV9leHB0KGZpc3Npb25fZXhwdCwgbm9ybT0idXBwZXJxdWFydGlsZSIpKQpmaXNzaW9uX2JveHBsb3QgPC0gc20ocGxvdF9ib3hwbG90KHVwX2V4cHQpKQpmaXNzaW9uX2JveHBsb3QKCmZpc3Npb25fZGVuc2l0eSA8LSBwbG90X2RlbnNpdHkobm9ybV9leHB0KQpmaXNzaW9uX2RlbnNpdHkkcGxvdApmaXNzaW9uX2RlbnNpdHkgPC0gcGxvdF9kZW5zaXR5KHNmX2V4cHQpCmZpc3Npb25fZGVuc2l0eSRwbG90CmZpc3Npb25fZGVuc2l0eSA8LSBwbG90X2RlbnNpdHkodG1fZXhwdCkKZmlzc2lvbl9kZW5zaXR5JHBsb3QKCmNvbXBhcmVfMTIgPC0gcGxvdF9zaW5nbGVfcXEoZmlzc2lvbl9leHB0LCB4PTEsIHk9MikKY29tcGFyZV8xMiRsb2cKYGBgCgojIyBTZWUgaG93IHRoZXkgY2x1c3RlcgoKT2ssIHNvIHdlIGNhbiBmdXJ0aGVyIGNoZWNrIG91dCBob3cgdGhlIGRhdGEgY2x1c3RlciB3aXRoIHJlc3BlY3QgdG8Kb25lIGFub3RoZXIuLi4KCmBgYHtyIGNsdXN0ZXJpbmd9CmZpc3Npb25fY29yIDwtIHBsb3RfY29yaGVhdChub3JtX2V4cHQpCmZpc3Npb25fY29yJHBsb3QKZmlzc2lvbl9jb3IgPC0gcGxvdF9jb3JoZWF0KGJhdGNobm9ybV9leHB0KQpmaXNzaW9uX2NvciRwbG90CmZpc3Npb25fZGlzIDwtIHBsb3RfZGlzaGVhdChub3JtX2V4cHQpCmZpc3Npb25fZGlzJHBsb3QKZmlzc2lvbl9kaXMgPC0gcGxvdF9kaXNoZWF0KGJhdGNobm9ybV9leHB0KQpmaXNzaW9uX2RpcyRwbG90CmBgYAoKIyB2YXJpYW5jZVBhcnRpdGlvbgoKdmFyaWFuY2VQYXJ0aXRpb24gbWF5IGJlIHVzZWQgdG8gc2VlayBvdXQgd2hpY2ggZXhwZXJpbWVudGFsIGZhY3RvcnMgY29ycmVsYXRlIHdpdGgKdGhlIG1vc3QgdmFyaWFuY2UgaW4gdGhlIGRhdGEuCgpgYGB7ciB2YXJpYW5jZVBhcnRpdGlvbn0KdGVzdF92YXJwYXJ0IDwtIHNpbXBsZV92YXJwYXJ0KGZpc3Npb25fZXhwdCwgcHJlZGljdG9yPU5VTEwsIGZhY3RvcnM9YygiY29uZGl0aW9uIiwiYmF0Y2giKSkKdGVzdF92YXJwYXJ0JHBlcmNlbnRfcGxvdAp0ZXN0X3ZhcnBhcnQkcGFydGl0aW9uX3Bsb3QKCiMjIEhlcmUsIGxldCB1cyB0ZXN0IHRoZSB2YXJpYW5jZSBjb250cmlidXRlZCBieSBzdHJhaW4sIHRpbWUsIGFuZCByZXBsaWNhdGUuCnRlc3RfdmFycGFydCA8LSBzaW1wbGVfdmFycGFydChmaXNzaW9uX2V4cHQsIHByZWRpY3Rvcj1OVUxMLCBmYWN0b3JzPWMoImNvbmRpdGlvbiIsICJzdHJhaW4iLCAibWludXRlIiwgInJlcGxpY2F0ZSIpKQp0ZXN0X3ZhcnBhcnQkcGVyY2VudF9wbG90CnRlc3RfdmFycGFydCRwYXJ0aXRpb25fcGxvdApgYGAKCllBWSEKCmBgYHtyIHN5c2luZm8sIHJlc3VsdHM9J2FzaXMnfQpwYW5kZXI6OnBhbmRlcihzZXNzaW9uSW5mbygpKQpgYGAK